#region License

// Copyright 2007-2008 Rory Plaire (codekaizen@gmail.com)
/*
 * This license governs use of the accompanying software. If you use the software, you
 * accept this license. If you do not accept the license, do not use the software.
 * 
 * 1. Definitions
 * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
 * same meaning here as under U.S. copyright law.
 * A "contribution" is the original software, or any additions or changes to the software.
 * A "contributor" is any person that distributes its contribution under this license.
 * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
 * 
 * 2. Grant of Rights
 * (A) Copyright Grant- Subject to the terms of this license, including the license conditions 
 *     and limitations in section 3, each contributor grants you a non-exclusive, worldwide, 
 *     royalty-free copyright license to reproduce its contribution, prepare derivative works 
 *     of its contribution, and distribute its contribution or any derivative works that you create.
 * (B) Patent Grant- Subject to the terms of this license, including the license conditions and 
 *     limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free 
 *     license under its licensed patents to make, have made, use, sell, offer for sale, import, 
 *     and/or otherwise dispose of its contribution in the software or derivative works of the 
 *     contribution in the software.
 * 
 * 3. Conditions and Limitations
 * (A) No Trademark License- This license does not grant you rights to use any contributors' 
 *     name, logo, or trademarks.
 * (B) If you bring a patent claim against any contributor over patents that you claim are 
 *     infringed by the software, your patent license from such contributor to the software 
 *     ends automatically.
 * (C) If you distribute any portion of the software, you must retain all copyright, patent, 
 *     trademark, and attribution notices that are present in the software.
 * (D) If you distribute any portion of the software in source code form, you may do so only under 
 *     this license by including a complete copy of this license with your distribution. If you 
 *     distribute any portion of the software in compiled or object code form, you may only do so 
 *     under a license that complies with this license.
 * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no 
 *     express warranties, guarantees or conditions. You may have additional consumer rights under 
 *     your local laws which this license cannot change. To the extent permitted under your local laws, 
 *     the contributors exclude the implied warranties of merchantability, fitness for a particular 
 *     purpose and non-infringement.
 * 
 */

#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using NPack.Interfaces;

namespace NPack.Matrix
{
    /// <summary>
    /// A vector.
    /// </summary>
    /// <typeparam name="T">Type of components in the vector.</typeparam>
    public class Vector<T> : IVector<T>, IVector<T, Vector<T>>, IEquatable<Vector<T>>,
                             IComparable<Vector<T>>, IComputable<Double, Vector<T>>
        where T : struct, IEquatable<T>, IComparable<T>,
            IComputable<Double, T>,
            IConvertible, IFormattable
    {
        private T[] _elements;

        /// <summary>
        /// Creates a new vector with the given number of components.
        /// </summary>
        /// <param name="componentCount">The number of components in the vector.</param>
        public Vector(Int32 componentCount)
        {
            _elements = new T[componentCount];
        }

        /// <summary>
        /// Creates a new vector with the given components.
        /// </summary>
        /// <param name="components">The components to initialize the vector to.</param>
        public Vector(params T[] components)
        {
            Components = components;
        }

        /// <summary>
        /// Creates a new vector with the given components.
        /// </summary>
        /// <param name="vector">The components to initialize the vector to.</param>
        public Vector(IVector<T> vector)
        {
            Components = vector.Components;
        }

        #region IComparable<Vector<T>> Members

        public Int32 CompareTo(Vector<T> other)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region Private helper methods

        private String PrintComponents()
        {
            var buffer = new StringBuilder();
            foreach (var component in Components)
            {
                if (buffer.Length > 255)
                {
                    buffer.Append(".....");
                    break;
                }

                buffer.Append(component);
                buffer.Append(", ");
            }

            buffer.Length -= 2;
            return buffer.ToString();
        }

        #endregion

        #region IComputable<double,Vector<T>> Members

        Vector<T> IComputable<Double, Vector<T>>.Set(Double value)
        {
            throw new NotImplementedException();
        }

        Vector<T> IComputable<Vector<T>>.Abs()
        {
            throw new NotImplementedException();
        }

        Vector<T> IComputable<Vector<T>>.Set(Double value)
        {
            throw new NotImplementedException();
        }

        public Boolean GreaterThan(Vector<T> value)
        {
            throw new NotImplementedException();
        }

        public Boolean GreaterThanOrEqualTo(Vector<T> value)
        {
            throw new NotImplementedException();
        }

        public Boolean LessThan(Vector<T> value)
        {
            throw new NotImplementedException();
        }

        public Boolean LessThanOrEqualTo(Vector<T> value)
        {
            throw new NotImplementedException();
        }

        Vector<T> IExponential<Vector<T>>.Power(Double exponent)
        {
            throw new NotImplementedException();
        }

        Vector<T> IExponential<Vector<T>>.Sqrt()
        {
            throw new NotImplementedException();
        }

        Vector<T> IExponential<Vector<T>>.Log(Double newBase)
        {
            throw new NotImplementedException();
        }

        Vector<T> IExponential<Vector<T>>.Log()
        {
            throw new NotImplementedException();
        }

        Vector<T> IExponential<Vector<T>>.Exp()
        {
            throw new NotImplementedException();
        }

        Vector<T> IAddable<Double, Vector<T>>.Add(Double b)
        {
            throw new NotImplementedException();
        }

        Vector<T> ISubtractable<Double, Vector<T>>.Subtract(Double b)
        {
            throw new NotImplementedException();
        }

        Vector<T> IMultipliable<Double, Vector<T>>.Multiply(Double b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IEquatable<Vector<T>> Members

        public Boolean Equals(Vector<T> other)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IVector<T,Vector<T>> Members

        /// <summary>
        /// Creates a component-by-component copy of the vector.
        /// </summary>
        /// <returns>A copy of the vector.</returns>
        public Vector<T> Clone()
        {
            T[] componetsCopy = new T[Components.Length];
            Array.Copy(Components, componetsCopy, componetsCopy.Length);
            return new Vector<T>(componetsCopy);
        }

        /// <summary>
        /// Returns the vector multiplied by -1.
        /// </summary>
        /// <returns>The vector when multiplied by -1.</returns>
        public Vector<T> Negative()
        {
            Vector<T> negated = Clone();

            for (Int32 i = 0; i < negated.ComponentCount; i++)
            {
                negated[i] = negated[i].Negative();
            }

            return negated;
        }

        public Double Dot(Vector<T> vector)
        {
            throw new NotImplementedException();
        }

        public Vector<T> Cross(Vector<T> vector)
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IComputable<Double, IVector<T, Vector<T>>>.Set(Double value)
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IComputable<IVector<T, Vector<T>>>.Abs()
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IComputable<IVector<T, Vector<T>>>.Set(Double value)
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> INegatable<IVector<T, Vector<T>>>.Negative()
        {
            throw new NotImplementedException();
        }

        public IVector<T, Vector<T>> Subtract(IVector<T, Vector<T>> b)
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IHasZero<IVector<T, Vector<T>>>.Zero
        {
            get { throw new NotImplementedException(); }
        }

        public IVector<T, Vector<T>> Add(IVector<T, Vector<T>> b)
        {
            throw new NotImplementedException();
        }

        public IVector<T, Vector<T>> Divide(IVector<T, Vector<T>> b)
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IHasOne<IVector<T, Vector<T>>>.One
        {
            get { throw new NotImplementedException(); }
        }

        public IVector<T, Vector<T>> Multiply(IVector<T, Vector<T>> b)
        {
            throw new NotImplementedException();
        }

        public Boolean GreaterThan(IVector<T, Vector<T>> value)
        {
            throw new NotImplementedException();
        }

        public Boolean GreaterThanOrEqualTo(IVector<T, Vector<T>> value)
        {
            throw new NotImplementedException();
        }

        public Boolean LessThan(IVector<T, Vector<T>> value)
        {
            throw new NotImplementedException();
        }

        public Boolean LessThanOrEqualTo(IVector<T, Vector<T>> value)
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IExponential<IVector<T, Vector<T>>>.Power(Double exponent)
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IExponential<IVector<T, Vector<T>>>.Sqrt()
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IExponential<IVector<T, Vector<T>>>.Log(Double newBase)
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IExponential<IVector<T, Vector<T>>>.Log()
        {
            throw new NotImplementedException();
        }

        IVector<T, Vector<T>> IExponential<IVector<T, Vector<T>>>.Exp()
        {
            throw new NotImplementedException();
        }

        public IVector<T, Vector<T>> Add(Double b)
        {
            throw new NotImplementedException();
        }

        public IVector<T, Vector<T>> Subtract(Double b)
        {
            throw new NotImplementedException();
        }

        public IVector<T, Vector<T>> Multiply(Double b)
        {
            throw new NotImplementedException();
        }

        public Boolean Equals(IVector<T, Vector<T>> other)
        {
            throw new NotImplementedException();
        }

        public Int32 CompareTo(IVector<T, Vector<T>> other)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IVector<T> Members

        /// <summary>
        /// Gets or sets a component in the vector.
        /// </summary>
        /// <param name="index">The index of the component.</param>
        /// <returns>The value of the component at the given <paramref name="index"/>.</returns>
        public T this[Int32 index]
        {
            get
            {
                if (index < 0 || index >= ComponentCount)
                {
                    throw new ArgumentOutOfRangeException("index", index,
                                                          "Indexer must be between 0 and ComponentCount.");
                }

                return Components[index];
            }
            set
            {
                if (index < 0 || index >= ComponentCount)
                {
                    throw new ArgumentOutOfRangeException("index", index,
                                                          "Indexer must be between 0 and ComponentCount.");
                }

                Components[index] = value;
            }
        }

        public void GetComponents(out T a, out T b)
        {
            throw new NotImplementedException();
        }

        public void GetComponents(out T a, out T b, out T c)
        {
            throw new NotImplementedException();
        }

        public void GetComponents(out T a, out T b, out T c, out T d)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Gets the number of components in the vector.
        /// </summary>
        public Int32 ComponentCount
        {
            get { return _elements.Length; }
        }

        /// <summary>
        /// Gets or sets the vector component array.
        /// </summary>
        public T[] Components
        {
            get { return _elements; }
            set
            {
                _elements = new T[value.Length];
                Array.Copy(value, _elements, value.Length);
            }
        }

        /// <summary>
        /// Gets an enumerator which enumerates over the vector's components.
        /// </summary>
        /// <returns>An <see cref="IEnumerator{T}"/> which returns the vectors components when iterated.</returns>
        public IEnumerator<T> GetEnumerator()
        {
            for (Int32 i = 0; i < ComponentCount; i++)
            {
                yield return this[i];
            }
        }

        public Int32 CompareTo(IMatrix<T> other)
        {
            throw new NotImplementedException();
        }

        public IMatrix<T> Abs()
        {
            throw new NotImplementedException();
        }

        public IMatrix<T> Set(Double value)
        {
            throw new NotImplementedException();
        }

        //IMatrix<T> INegatable<IMatrix<T>>.Negative()
        //{
        //    throw new NotImplementedException();
        //}

        public IMatrix<T> Subtract(IMatrix<T> b)
        {
            throw new NotImplementedException();
        }

        public IMatrix<T> Add(IMatrix<T> b)
        {
            throw new NotImplementedException();
        }

        public IMatrix<T> Multiply(IMatrix<T> b)
        {
            throw new NotImplementedException();
        }

        public Boolean GreaterThan(IMatrix<T> value)
        {
            throw new NotImplementedException();
        }

        public Boolean GreaterThanOrEqualTo(IMatrix<T> value)
        {
            throw new NotImplementedException();
        }

        public Boolean LessThan(IMatrix<T> value)
        {
            throw new NotImplementedException();
        }

        public Boolean LessThanOrEqualTo(IMatrix<T> value)
        {
            throw new NotImplementedException();
        }

        public IMatrix<T> Power(Double exponent)
        {
            throw new NotImplementedException();
        }

        public IMatrix<T> Sqrt()
        {
            throw new NotImplementedException();
        }

        public IMatrix<T> Log(Double newBase)
        {
            throw new NotImplementedException();
        }

        public IMatrix<T> Log()
        {
            throw new NotImplementedException();
        }

        public IMatrix<T> Exp()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IVector<T> Member

        IVector<T> IVector<T>.Clone()
        {
            return Clone();
        }

        int IVector<T>.ComponentCount
        {
            get { return ComponentCount; }
        }

        T[] IVector<T>.Components
        {
            get { return Components; }
            set { throw new NotImplementedException(); }
        }

        IVector<T> IVector<T>.Negative()
        {
            throw new NotImplementedException();
        }

        //T IVector<T>.this[int index]
        //{
        //    get
        //    {
        //        return this[index];
        //    }
        //    set
        //    {
        //        this[index] = value;
        //    }
        //}

        //void IVector<T>.GetComponents(out T a, out T b)
        //{
        //    this.GetComponents(out a, out b);
        //}

        //void IVector<T>.GetComponents(out T a, out T b, out T c)
        //{
        //    this.GetComponents(out a, out b, out c);
        //}

        //void IVector<T>.GetComponents(out T a, out T b, out T c, out T d)
        //{
        //    this.GetComponents(out a, out b, out c, out d);
        //}

        #endregion

        #region IEquatable<IMatrix<T>> Member

        //bool IEquatable<IMatrix<T>>.Equals(IMatrix<T> other)
        //{
        //    throw new NotImplementedException();
        //}

        #endregion

        #region IComparable<IMatrix<T>> Member

        //int IComparable<IMatrix<T>>.CompareTo(IMatrix<T> other)
        //{
        //    throw new NotImplementedException();
        //}

        #endregion

        #region IComputable<IMatrix<T>> Member

        //IMatrix<T> IComputable<IMatrix<T>>.Abs()
        //{
        //    throw new NotImplementedException();
        //}

        //IMatrix<T> IComputable<IMatrix<T>>.Set(double value)
        //{
        //    throw new NotImplementedException();
        //}

        #endregion

        #region ISubtractable<IMatrix<T>> Member

        //IMatrix<T> ISubtractable<IMatrix<T>>.Subtract(IMatrix<T> b)
        //{
        //    throw new NotImplementedException();
        //}

        #endregion

        #region IHasZero<IMatrix<T>> Member

        //IMatrix<T> IHasZero<IMatrix<T>>.Zero
        //{
        //    get { throw new NotImplementedException(); }
        //}

        #endregion

        #region IAddable<IMatrix<T>> Member

        //IMatrix<T> IAddable<IMatrix<T>>.Add(IMatrix<T> b)
        //{
        //    throw new NotImplementedException();
        //}

        #endregion

        #region IHasOne<IMatrix<T>> Member

        //IMatrix<T> IHasOne<IMatrix<T>>.One
        //{
        //    get { throw new NotImplementedException(); }
        //}

        #endregion

        #region IMultipliable<IMatrix<T>> Member

        //IMatrix<T> IMultipliable<IMatrix<T>>.Multiply(IMatrix<T> b)
        //{
        //    throw new NotImplementedException();
        //}

        #endregion

        #region IBooleanComparable<IMatrix<T>> Member

        //bool IBooleanComparable<IMatrix<T>>.GreaterThan(IMatrix<T> value)
        //{
        //    throw new NotImplementedException();
        //}

        //bool IBooleanComparable<IMatrix<T>>.GreaterThanOrEqualTo(IMatrix<T> value)
        //{
        //    throw new NotImplementedException();
        //}

        //bool IBooleanComparable<IMatrix<T>>.LessThan(IMatrix<T> value)
        //{
        //    throw new NotImplementedException();
        //}

        //bool IBooleanComparable<IMatrix<T>>.LessThanOrEqualTo(IMatrix<T> value)
        //{
        //    throw new NotImplementedException();
        //}

        #endregion

        #region IExponential<IMatrix<T>> Member

        //IMatrix<T> IExponential<IMatrix<T>>.Power(double exponent)
        //{
        //    throw new NotImplementedException();
        //}

        //IMatrix<T> IExponential<IMatrix<T>>.Sqrt()
        //{
        //    throw new NotImplementedException();
        //}

        //IMatrix<T> IExponential<IMatrix<T>>.Log(double newBase)
        //{
        //    throw new NotImplementedException();
        //}

        //IMatrix<T> IExponential<IMatrix<T>>.Log()
        //{
        //    throw new NotImplementedException();
        //}

        //IMatrix<T> IExponential<IMatrix<T>>.Exp()
        //{
        //    throw new NotImplementedException();
        //}

        #endregion

        #region IEnumerable<T> Member

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion

        #region IComputable<double,IVector<T>> Member

        IVector<T> IComputable<double, IVector<T>>.Set(double value)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IComputable<IVector<T>> Member

        IVector<T> IComputable<IVector<T>>.Abs()
        {
            throw new NotImplementedException();
        }

        IVector<T> IComputable<IVector<T>>.Set(double value)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region INegatable<IVector<T>> Member

        IVector<T> INegatable<IVector<T>>.Negative()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region ISubtractable<IVector<T>> Member

        IVector<T> ISubtractable<IVector<T>>.Subtract(IVector<T> b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IHasZero<IVector<T>> Member

        IVector<T> IHasZero<IVector<T>>.Zero
        {
            get { throw new NotImplementedException(); }
        }

        #endregion

        #region IAddable<IVector<T>> Member

        IVector<T> IAddable<IVector<T>>.Add(IVector<T> b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IDivisible<IVector<T>> Member

        IVector<T> IDivisible<IVector<T>>.Divide(IVector<T> b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IHasOne<IVector<T>> Member

        IVector<T> IHasOne<IVector<T>>.One
        {
            get { throw new NotImplementedException(); }
        }

        #endregion

        #region IMultipliable<IVector<T>> Member

        IVector<T> IMultipliable<IVector<T>>.Multiply(IVector<T> b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IBooleanComparable<IVector<T>> Member

        bool IBooleanComparable<IVector<T>>.GreaterThan(IVector<T> value)
        {
            throw new NotImplementedException();
        }

        bool IBooleanComparable<IVector<T>>.GreaterThanOrEqualTo(IVector<T> value)
        {
            throw new NotImplementedException();
        }

        bool IBooleanComparable<IVector<T>>.LessThan(IVector<T> value)
        {
            throw new NotImplementedException();
        }

        bool IBooleanComparable<IVector<T>>.LessThanOrEqualTo(IVector<T> value)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IExponential<IVector<T>> Member

        IVector<T> IExponential<IVector<T>>.Power(double exponent)
        {
            throw new NotImplementedException();
        }

        IVector<T> IExponential<IVector<T>>.Sqrt()
        {
            throw new NotImplementedException();
        }

        IVector<T> IExponential<IVector<T>>.Log(double newBase)
        {
            throw new NotImplementedException();
        }

        IVector<T> IExponential<IVector<T>>.Log()
        {
            throw new NotImplementedException();
        }

        IVector<T> IExponential<IVector<T>>.Exp()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IAddable<double,IVector<T>> Member

        IVector<T> IAddable<double, IVector<T>>.Add(double b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region ISubtractable<double,IVector<T>> Member

        IVector<T> ISubtractable<double, IVector<T>>.Subtract(double b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IMultipliable<double,IVector<T>> Member

        IVector<T> IMultipliable<double, IVector<T>>.Multiply(double b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IDivisible<double,IVector<T>> Member

        IVector<T> IDivisible<double, IVector<T>>.Divide(double b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IEquatable<IVector<T>> Member

        bool IEquatable<IVector<T>>.Equals(IVector<T> other)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IComparable<IVector<T>> Member

        int IComparable<IVector<T>>.CompareTo(IVector<T> other)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IVector<T> implementation

        #region IComputable<double,Vector<T>> Members

        public Vector<T> Add(Vector<T> b)
        {
            return MatrixProcessor<T>.Add(this, b);
        }

        public Vector<T> Subtract(Vector<T> b)
        {
            return MatrixProcessor<T>.Subtract(this, b);
        }

        Vector<T> IHasZero<Vector<T>>.Zero
        {
            get { return new Vector<T>(); }
        }

        public Vector<T> Multiply(Vector<T> b)
        {
            throw new NotSupportedException("Vector-Vector multiplication is not supported.");
        }

        public Vector<T> Divide(Vector<T> b)
        {
            throw new NotSupportedException("Vector-Vector division is not supported.");
        }

        Vector<T> IDivisible<Double, Vector<T>>.Divide(Double b)
        {
            throw new NotSupportedException("Vector-Vector division is not supported.");
        }

        Vector<T> IHasOne<Vector<T>>.One
        {
            get
            {
                Vector<T> v = new Vector<T>(ComponentCount);

                for (Int32 i = 0; i < ComponentCount; i++)
                {
                    v[i] = default(T).One;
                }

                return v;
            }
        }

        #endregion

        #region IVector<T,Vector<T>> Members

        public IVector<T, Vector<T>> Divide(Double b)
        {
            throw new NotImplementedException();
        }

        #endregion

        #endregion

        #region IMatrix implementation

        public IMatrix<T> One
        {
            get
            {
                Vector<T> v = new Vector<T>(ComponentCount);

                for (Int32 i = 0; i < ComponentCount; i++)
                {
                    v[i] = default(T).One;
                }

                return v;
            }
        }

        public IMatrix<T> Zero
        {
            get { return new Vector<T>(); }
        }

        /// <summary>
        /// Gets the determinant for the vector, if it is a single element.
        /// </summary>
        public Double Determinant
        {
            get { throw new NotSupportedException(); }
        }

        /// <summary>
        /// Gets the number of columns in the matrix. Not supported for Vector{T}.
        /// </summary>
        /// <exception cref="NotSupportedException">Thrown when accessed.</exception>
        public Int32 ColumnCount
        {
            get { throw new NotSupportedException(); }
        }

        /// <summary>
        /// Gets the format of the matrix, either row-major or column-major.
        /// </summary>
        public MatrixFormat Format
        {
            get { return MatrixFormat.Unspecified; }
        }

        /// <summary>
        /// Gets true if the matrix is singular (non-invertible). 
        /// </summary>
        public Boolean IsSingular
        {
            get { return ComponentCount != 1; }
        }

        /// <summary>
        /// Gets true if the matrix is invertible (non-singular). Only true for Vector{T} when there is one element.
        /// </summary>
        public Boolean IsInvertible
        {
            get { return !IsSingular; }
        }

        /// <summary>
        /// Gets the inverse of the matrix, if one exists. Only true for Vector{T} when there is one element.
        /// </summary>
        public IMatrix<T> Inverse
        {
            get { throw new NotSupportedException(); }
        }

        /// <summary>
        /// Gets true if the matrix is square. Only true for Vector{T} when there is one element.
        /// </summary>
        public Boolean IsSquare
        {
            get { return (_elements.Length == 1); }
        }

        /// <summary>
        /// Gets true if the matrix is symmetrical. Only true for Vector{T} when there is one element.
        /// </summary>
        public Boolean IsSymmetrical
        {
            get { return IsSquare; }
        }

        /// <summary>
        /// Gets the number of rows in the matrix. Not supported for Vector{T}.
        /// </summary>
        /// <exception cref="NotSupportedException">Thrown when accessed.</exception>
        public Int32 RowCount
        {
            get { throw new NotSupportedException(); }
        }

        /// <summary>
        /// Gets or sets an element in the matrix.
        /// </summary>
        /// <param name="row">The index of the row of the element.</param>
        /// <param name="column">The index of the column of the element.</param>
        /// <returns>The value of the element at the specified row and column.</returns>
        public T this[Int32 row, Int32 column]
        {
            get
            {
                if (row != 0)
                {
                    throw new ArgumentOutOfRangeException("row", row, "Row must be 0 for a Vector instance.");
                }

                if (column < 0 || column >= ComponentCount)
                {
                    throw new ArgumentOutOfRangeException("column", column, "Column must be between 0 and ColumnCount.");
                }

                return this[column];
            }
            set
            {
                if (row != 0)
                {
                    throw new ArgumentOutOfRangeException("row", row, "Row must be 0 for a Vector instance.");
                }

                if (column < 0 || column >= ComponentCount)
                {
                    throw new ArgumentOutOfRangeException("column", column, "Column must be between 0 and ColumnCount.");
                }

                this[column] = value;
            }
        }

        /// <summary>
        /// Gets a row of the matrix
        /// </summary>
        /// <param name="row">The row index</param>
        /// <returns>The requested row</returns>
        public T[] GetRow(int row)
        {
            if (row < 0 || row > _elements.Length)
                throw new ArgumentOutOfRangeException("row");

            return new [] { _elements[row] };
        }

        /// <summary>
        /// Gets a column of the matrix
        /// </summary>
        /// <param name="column">The column index</param>
        /// <returns>The requested column</returns>
        public T[] GetColumn(int column)
        {
            if (column != 0)
                throw new ArgumentOutOfRangeException("column");
            var res = new T[_elements.Length];
            Array.Copy(_elements, res, _elements.Length);
            return res;
        }

        /// <summary>
        /// Returns the matrix as jagged array, <see cref="MatrixFormat.RowMajor"/>
        /// </summary>
        public T[][] GetAsJaggedArray()
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Sets the matrix values from the provided <see cref="source"/>
        /// </summary>
        /// <remarks>The <paramref name="source"/> is interpreted as being <see cref="MatrixFormat.RowMajor"/></remarks>
        /// <exception cref="InvalidOperationException">
        /// Thrown if the format of <paramref name="source"/> does not match the matrix' size.
        /// </exception>
        public void SetFromJaggedArray(T[][] source)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Makes an element-by-element copy of the matrix.
        /// </summary>
        /// <returns>An exact copy of the matrix.</returns>
        IMatrix<T> IMatrix<T>.Clone()
        {
            return Clone();
        }

        /// <summary>
        /// Gets a submatrix. Not supported for Vector{T}.
        /// </summary>
        /// <param name="rowIndexes">The indexes of the rows to include.</param>
        /// <param name="j0">The starting column to include.</param>
        /// <param name="j1">The ending column to include.</param>
        /// <returns>A submatrix with rows given by <paramref name="rowIndexes"/> and columns <paramref name="j0"/> 
        /// through <paramref name="j1"/>.</returns>
        IMatrix<T> IMatrix<T>.GetMatrix(Int32[] rowIndexes, Int32 j0, Int32 j1)
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// Returns the transpose of the matrix. Returns a clone for Vector{T}, since vectors are storage agnostic.
        /// </summary>
        /// <returns>A <see cref="Clone"/> of the called-on vector.</returns>
        IMatrix<T> IMatrix<T>.Transpose()
        {
            return Clone();
        }

        ///<summary>
        /// Tests if this vector is equal to other <see cref="IMatrix{T}"/>.
        ///</summary>
        ///<param name="other">Matrix to test</param>
        ///<returns>True if e</returns>
        public Boolean Equals(IMatrix<T> other)
        {
            if (ReferenceEquals(other, null))
            {
                return false;
            }

            if (ReferenceEquals(other, this))
            {
                return true;
            }

            if (other is IVector<T>)
            {
                var v = other as IVector<T>;

                if (v.ComponentCount != ComponentCount)
                {
                    return false;
                }

                for (Int32 componentIndex = 0; componentIndex < ComponentCount; componentIndex++)
                {
                    if (!v[componentIndex].Equals(this[componentIndex]))
                    {
                        return false;
                    }
                }
            }

            if (other.Format == MatrixFormat.ColumnMajor)
            {
                if (other.ColumnCount != 1 || other.RowCount != ComponentCount)
                {
                    return false;
                }

                for (Int32 elementIndex = 0; elementIndex < ComponentCount; elementIndex++)
                {
                    if (!other[elementIndex, 0].Equals(this[elementIndex]))
                    {
                        return false;
                    }
                }
            }

            if (other.Format == MatrixFormat.RowMajor)
            {
                if (other.RowCount != 1 || other.ColumnCount != ComponentCount)
                {
                    return false;
                }

                for (Int32 elementIndex = 0; elementIndex < ComponentCount; elementIndex++)
                {
                    if (!other[0, elementIndex].Equals(this[elementIndex]))
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        #endregion

        /// <summary>
        /// Gets a String representation of the vector.
        /// </summary>
        /// <returns>A String describing the vector.</returns>
        public override String ToString()
        {
            return String.Format("Vector<{0}> [{1}]", typeof (T), PrintComponents());
        }
    }
}